---
title: SAIF.Application.Claim business rules
summary: Business rules enforced by the claim-context application manager library, including claim access restrictions and context-change behaviors.
status: draft
owner: SAIF Claims BOF team
last_reviewed: 2026-08-21
library: SAIF.Application.Claim
reference_type: embedded
---

# SAIF.Application.Claim business rules

This page captures business rules enforced by `SAIF.Application.Claim`.

## BR-CLM-001 Conflict-claim access restriction

| Field | Value |
| --- | --- |
| **Statement** | A user without conflict-claim access cannot fully access a claim flagged as a worker conflict; access is denied outright (not merely view-only) unless a security override applies. |
| **Trigger** | `ClaimAppManager.OnCheckSecurity()` runs after any successful context change (`ChangeContext`), when `ClaimData.IsWorkerConflict` is true. |
| **Enforcement** | `ClaimSecurity.CheckClaim(inClaim)` sets `m_ConflictAccess = False` when `inClaim.IsWorkerConflict` and `Not UserAccess.ConflictAccess`; `ClaimAppManager.OnCheckSecurity()` then calls `MarkNoAccess()` and sets `Message = ConfidentialAccessDeniedMessage` when `Not ClaimSecurity.ConflictAccess AndAlso Not CheckForSecurityOverride()`. |
| **Outcome** | Access is fully denied (`MarkNoAccess`) and a confidential-claim error message is shown, unless `CheckForSecurityOverride()` returns true. The override delegates to `ClaimServices.HasOverrideAcess(DPI, ClaimData.ClaimID, SecurityPrincipal.UserName.ToString)` — **`ClaimServices` is not defined anywhere in this library or elsewhere in the scanned repository; the owning library and internal logic of this override cannot be verified**.** |
| **Source** | `SAIF.Application.Claim\ClaimSecurity.vb`; `SAIF.Application.Claim\ClaimAppManager.vb` |

---

## BR-CLM-002 Exposure-claim access restriction

| Field | Value |
| --- | --- |
| **Statement** | A user without exposure-claim access does not have exposure access to a claim flagged as an exposure claim. |
| **Trigger** | `ClaimSecurity.CheckClaim(inClaim)` evaluated whenever `OnCheckSecurity()` runs and `inClaim.IsExposure` is true. |
| **Enforcement** | `m_ExposureAccess = False` is set when `inClaim.IsExposure` and `Not UserAccess.ExposureAccess`. |
| **Outcome** | `ClaimSecurity.ExposureAccess` returns `False`; callers outside this library (e.g. screen-level field/section visibility logic) are expected to check this flag to restrict exposure-related data — this library does not itself gate overall access on it beyond exposing the property*. |
| **Source** | `SAIF.Application.Claim\ClaimSecurity.vb` |

---

## BR-CLM-003 Health-issue claim access restriction

| Field | Value |
| --- | --- |
| **Statement** | A user without exposure-claim access does not have health-issue access to a claim flagged as both a health-issue and an exposure claim. |
| **Trigger** | `ClaimSecurity.CheckClaim(inClaim)` when `inClaim.IsHealthIssue AndAlso inClaim.IsExposure` is true. |
| **Enforcement** | `m_HealthIssueAccess = False` is set when `inClaim.IsHealthIssue`, `inClaim.IsExposure`, and `Not UserAccess.ExposureAccess`. Health-issue access is gated by `ExposureAccess`, not a separate `HealthIssueAccess` check, even though `ClaimUserAccess.HealthIssueAccess` (backed by the `CollateralHealthClaim` AD resource key) exists and is never consulted by `ClaimSecurity.CheckClaim`*. |
| **Outcome** | `ClaimSecurity.HealthIssueAccess` returns `False` only when exposure access is also lacking; if `IsHealthIssue` is true but `IsExposure` is false, `HealthIssueAccess` always remains `True` regardless of the user's actual health-issue access rights*. **Tech debt**: the `CollateralHealthClaim` AD resource key and its `ClaimUserAccess.HealthIssueAccess` property are declared and exposed but never consulted anywhere in this library's rule evaluation, making the resource key effectively dead from this library's perspective. Whether this is an intentional reserved/superseded key or a latent defect could not be determined from this library's source alone**. |
| **Source** | `SAIF.Application.Claim\ClaimSecurity.vb`; `SAIF.Application.Claim\ClaimUserAccess.vb` |

---

## BR-CLM-004 Hostile secure claim access restriction

| Field | Value |
| --- | --- |
| **Statement** | A user without secure-claim access does not have secure-claim access to a claim flagged as involving a hostile worker. |
| **Trigger** | `ClaimSecurity.CheckClaim(inClaim)` when `inClaim.IsHostileWorker` is true. |
| **Enforcement** | `m_SecureClaimAccess = False` is set when `inClaim.IsHostileWorker` and `Not UserAccess.SecureClaimAccess`. |
| **Outcome** | `ClaimSecurity.SecureClaimAccess` returns `False`; this library does not itself gate `MarkNoAccess`/`MarkViewOnly` on this flag directly (only `ConflictAccess` triggers hard denial in `OnCheckSecurity`) — callers are expected to consult `SecureClaimAccess` separately*. |
| **Source** | `SAIF.Application.Claim\ClaimSecurity.vb` |

---

## BR-CLM-005 Default view-only access on context change

| Field | Value |
| --- | --- |
| **Statement** | Every successful claim/worker context change resets the user's access level to view-only before any further access evaluation occurs. |
| **Trigger** | `ChangeContext()` → `OnCheckSecurity()` runs whenever `ContextSet` becomes true after a `SetClaimContext`/`SetWorkerContext` call. |
| **Enforcement** | `ClaimAppManager.OnCheckSecurity()` calls `MarkViewOnly()` unconditionally as its first executable action after `CheckClaim`. |
| **Outcome** | The security role is set to view-only by default; only the conflict-access check can subsequently escalate this to `MarkNoAccess()` (full denial). Write/edit access is presumed to be granted elsewhere (in the concrete subclass or `SAIF.Application`, not traceable from this library's source)**. |
| **Source** | `SAIF.Application.Claim\ClaimAppManager.vb` |

---

## BR-CLM-006 Blank placeholder claim number rejected

| Field | Value |
| --- | --- |
| **Statement** | An empty claim number, or the literal placeholder text "claim #" (case-insensitive), is not accepted as a valid claim context. |
| **Trigger** | `SetClaimContext(inClaimNumber As String)` is called with a claim-number string. |
| **Enforcement** | `If inClaimNumber.Trim.Length > 0 AndAlso Not inClaimNumber.ToLower.Equals(MENUCONTEXTLABEL_LOWER)` guards the valid path; `MENUCONTEXTLABEL_LOWER` is `"claim #"`. |
| **Outcome** | If the guard fails, `ClaimData` is cleared, `MarkContextNotSet()` is called, and `Message = ClaimAppConstants.PLEASEENTERCLAIM` ("Please enter a valid claim number.") is shown. **Tech debt**: `SetClaimContext(inClaimID As Decimal)` (the decimal overload) does not apply this same validation flow — it only calls `MarkContextSet()` directly and does not call `ChangeContext()`/`OnCheckSecurity()`/`OnRetrieve()`, an asymmetry versus the string overload that may be an intentional lightweight ID-only context set or an inconsistency**. |
| **Source** | `SAIF.Application.Claim\ClaimAppManager.vb`; `SAIF.Application.Claim\ClaimAppConstants.vb` |

---

## BR-CLM-007 Claim-not-found messaging

| Field | Value |
| --- | --- |
| **Statement** | If claim data cannot be retrieved for a set context, the claim is reported as not found. |
| **Trigger** | `OnContextChanged()` runs after `GetClaimData()` retrieves (or fails to retrieve) claim data for the current context. |
| **Enforcement** | `Message = ClaimAppConstants.CLAIMNOTFOUND` is set at the start of `OnContextChanged()`; it is only cleared (`Message = String.Empty`) and `MarkContextSet()` called if `m_ClaimData.IsValid` is true after `GetClaimData()`. |
| **Outcome** | If `ClaimData.IsValid` is false, the "Error: Claim not found." message persists and the context is not marked set. |
| **Source** | `SAIF.Application.Claim\ClaimAppManager.vb`; `SAIF.Application.Claim\ClaimAppConstants.vb` |

## Notes
- **BR-CLM-001 unresolved dependency**: the security-override bypass for the conflict-claim hard-denial gate delegates to `ClaimServices.HasOverrideAcess`, a type not defined anywhere in this library or the rest of the scanned repository; its owning package/library could not be resolved**.
- **BR-CLM-003 tech debt**: the `CollateralHealthClaim`/`ClaimUserAccess.HealthIssueAccess` resource key is declared but never consulted by `ClaimSecurity.CheckClaim` — see the Outcome field above.
- **BR-CLM-006 tech debt**: the `SetClaimContext(inClaimID As Decimal)` overload does not trigger the same context-change/security/retrieval pipeline as the string overload — see the Outcome field above.
- Mark inferred statements with `*` and unknown statements with `**`. Do not use bold inline confidence labels.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Security and authorization](security-authorization.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Application.Claim\ClaimAppManager.vb`
- `SAIF.Application.Claim\ClaimSecurity.vb`
- `SAIF.Application.Claim\ClaimUserAccess.vb`
- `SAIF.Application.Claim\ClaimAppConstants.vb`
